package jm.easyconfig;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class CfgContextEnvironmentAgent implements BeanPostProcessor, ApplicationContextAware {
	CfgContextEnvironmentAware aware;
	boolean sameContainer;

	public CfgContextEnvironmentAgent() {
		aware = CfgContextEnvironmentAware.getSharedInstance();

		CfgHelper.logger.info("{} is created to delegate {}.", this, aware);

		if (aware == null) {
			CfgHelper.logger.error(
					"The bean of CfgContextEnvironmentAware does not exist when to create CfgContextEnvironmentAgent.\n"
							+ " CfgContextEnvironmentAgent should been created and used in spring child container,"
							+ " to collect these beans in child container.");
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		if (aware == null)
			return;

		if (CfgContextEnvironmentAware.applicationContext == applicationContext) {
			sameContainer = true;
			CfgHelper.logger.error("The beans of {} and {} should not exist in the same spring container.", this,
					aware);
		}

		ApplicationContext parent = applicationContext.getParent();
		if (parent != null && CfgContextEnvironmentAware.applicationContext == parent) {
			CfgHelper.logger.info("{} is initialized correctly in {} as CfgContextEnvironmentAware's delegate for {}.",
					this, applicationContext, CfgContextEnvironmentAware.applicationContext);
		}
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (aware == null || sameContainer)
			return bean;

		return aware.postProcessBeforeInitialization(bean, beanName + "@Child");
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (aware == null || sameContainer)
			return bean;

		return aware.postProcessAfterInitialization(bean, beanName + "@Child");
	}

}
